#include "infoassembling.h"

#define PEN_WIDTH 0.1
#define NONE "none"
#define DRIVING "driving"
#define SIDEWALK "sidewalk"
#define BORDER "border"
#define STANDARD "standard"
#define SOLID "solid"
#define BROKEN "broken"


InfoAssembling::InfoAssembling()
{
}

InfoAssembling::~InfoAssembling()
{
}

RoadMapItem *InfoAssembling::getMap()
{
    RoadMapItem *pRoadMapItem = new RoadMapItem();
    QPolygonF laneFilling;
    QPen pen;
    pen.setWidthF(PEN_WIDTH);

    for(int i = 0; i < m_qvecQvecQvecRoadLaesectionLaneData.size(); ++i)
    {
        QVector<QVector<QPointF> > qvecQvecRoadLaesectionLaneData = m_qvecQvecQvecRoadLaesectionLaneData[i];
        vector<Lane> vecLaneInformation = m_vecVecLaneInformation[i];
        RoadItem *pRoadItem = new RoadItem();
        int iLaneId = m_vecLaneId[i];

        for(int j = 0; j < iLaneId; ++j)
        {
            LaneItem *pLaneItem = new LaneItem;
            laneFilling = __RODADATA->fillLaneData(qvecQvecRoadLaesectionLaneData[j],qvecQvecRoadLaesectionLaneData[j+1]);
            __RODADATA->setYOppositeNumber(laneFilling);
            pLaneItem->setPolygon(laneFilling);
            pLaneItem->setPen(pen);
            pRoadItem->addToGroup(pLaneItem);
            QObject::connect(pLaneItem, SIGNAL(sigId(int)), pRoadItem, SLOT(onRoadID(int)));
        }

        for(unsigned int j = iLaneId + 1; j < vecLaneInformation.size(); ++j)
        {
            LaneItem *pLaneItem = new LaneItem;
            laneFilling = __RODADATA->fillLaneData(qvecQvecRoadLaesectionLaneData[j],qvecQvecRoadLaesectionLaneData[j-1]);
            __RODADATA->setYOppositeNumber(laneFilling);
            pLaneItem->setPen(pen);
            pLaneItem->setPolygon(laneFilling);
            pRoadItem->addToGroup(pLaneItem);
            QObject::connect(pLaneItem, SIGNAL(sigId(int)), pRoadItem, SLOT(onRoadID(int)));
        }

        //pRoadItem->setShape(__RODADATA->fillLaneData(qvecQvecRoadLaesectionLaneData[0], qvecQvecRoadLaesectionLaneData[qvecQvecRoadLaesectionLaneData.size()-1]));
        pRoadMapItem->addToGroup(pRoadItem);
    }

    return pRoadMapItem;
}

RoadMapItem *InfoAssembling::transferRoadMapInfo(const MapInfo &mapInfo)
{
    RoadMapPoint roadMapPoint;
    RoadMapPaint roadMapPaint;
    RoadMapLane roadMapLane;
    mapInfo.getRoadSurfaceContourPoint(mapInfo.getRoad(), roadMapPoint);
    mapInfo.getRoadLaneSectionLevelPoint(roadMapPoint, roadMapPaint);
    transferLanesList(mapInfo, roadMapLane);

    RoadMapItem *pRoadMapItem = new RoadMapItem();
    setRoadMapFilling(roadMapPaint, roadMapLane, pRoadMapItem);
    setRoadMapLaneLine(roadMapPaint, roadMapLane, pRoadMapItem);
    pRoadMapItem->setJunction(mapInfo.getJunction());
    pRoadMapItem->setController(mapInfo.getController());

    // 后期提取出函数

    // 绘制车道
    for (int i = 0; i < roadMapPoint.size(); ++i)
    {
        // 每一个道路
        RoadItem *pRoadItem = new RoadItem();
        transferRoad(mapInfo.getRoad().at(i), pRoadItem); // 道路信息装入RoadItem

        RoadPoint roadPoint = roadMapPoint[i];
        RoadLane roadLane = roadMapLane[i]; // 道路数一致，所以共用下标
        pRoadItem->setPolygonPoint(getRoadShape(roadPoint));

        for (int j = 0; j < roadPoint.size(); ++j)
        {
            // 每一个车道段
            LaneSectionPoint laneSectionPoint = roadPoint[j];
            SectionLane sectionLane = roadLane[j];

            for (int k = 0; k < laneSectionPoint.size(); ++k)
            {
                // 每一个几何元素
                GeometryPoint qvecGeometry = laneSectionPoint[k].first;

                // 几何元素信息 一个车道段要同时传输全部几何元素
                int iIndexGeometry = laneSectionPoint[k].second;
                SGeometry geometry = mapInfo.getRoad().at(i).planView.qvecGeometry[iIndexGeometry];

                int startLaneIndex = stoi(sectionLane[0].id);
                LaneItem *pLaneItem;

                for (int n = 0; n < sectionLane.size(); ++n)
                {
                    QVector<QPointF> qvecData = qvecGeometry[n];
                    __RODADATA->setYOppositeNumber(qvecData);
                    pRoadItem->appendLaneLine(qvecData);
                    pRoadItem->appendLane(sectionLane[n]);

                    if(n < startLaneIndex)
                    {
                        //左车道
                        pLaneItem = createLaneItem(qvecGeometry[n], qvecGeometry[n+1]);
                    }
                    else if(n > startLaneIndex)
                    {
                        //右车道】
                        pLaneItem = createLaneItem(qvecGeometry[n], qvecGeometry[n-1]);
                    }
                    else
                    {
                        //LaneID等于0的情况，没有车道
                        continue;
                    }

                    transferLane(sectionLane[n], pLaneItem);
                    transferRoad(mapInfo.getRoad().at(i), pLaneItem); // 道路信息
                    transferLaneSection(mapInfo.getRoad().at(i).lanes.qvecLaneSection.at(j), pLaneItem); // 车道段信息
                    pLaneItem->setGeometry(geometry);

                    pRoadItem->addToGroup(pLaneItem);
                    pRoadItem->appendLaneItem(pLaneItem);
                    QObject::connect(pLaneItem, &LaneItem::sigLane, pRoadItem, &RoadItem::onRoad);
                    QObject::connect(pLaneItem, &LaneItem::sigClick, pRoadItem, &RoadItem::onClick);
                }
            }
        }

        pRoadMapItem->addToGroup(pRoadItem);
        QObject::connect(pRoadItem, &RoadItem::sigRoad, pRoadMapItem, &RoadMapItem::onMap);
    }

    return pRoadMapItem;
}

void InfoAssembling::transferRoad(const SRoad &road, RoadItem *pRoadItem)
{
    if(nullptr != pRoadItem)
    {
        pRoadItem->setId(road.id.c_str());
        pRoadItem->setType(road.roadType.type.c_str());
        pRoadItem->setObject(road.objects.qvecObject);
        pRoadItem->setElevations(road.elevationProfile.qvecElevation);
        pRoadItem->setLaneOffsets(road.lanes.qvecLaneOffset);
    }
}

void InfoAssembling::transferRoad(const SRoad &road, LaneItem *pLaneItem)
{
    if(nullptr != pLaneItem)
    {
        pLaneItem->setRoadId(road.id);
        pLaneItem->setRoadType(road.roadType.type);
    }
}

void InfoAssembling::transferLaneSection(const SLaneSection &laneSection, LaneItem *pLaneItem)
{
    if(nullptr != pLaneItem)
    {
        pLaneItem->setLaneSection(laneSection);
        pLaneItem->setLaneSectionS(laneSection.s);
        QVector<SLane> qvecLane;

        if(pLaneItem->getId().toInt() > 0)
        {
            qvecLane = laneSection.left.qvecLane;
        }
        else if(pLaneItem->getId().toInt() < 0)
        {
            qvecLane = laneSection.right.qvecLane;
        }
        else
        {
            qDebug() << "此LaneItemID非法";
        }

        for(SLane lane: qvecLane)
        {
            pLaneItem->appendWidth(std::stoi(lane.id), lane.width);
        }
    }
}

void InfoAssembling::transferLane(const SLane &lane, LaneItem *pLaneItem)
{
    if(nullptr != pLaneItem)
    {
        pLaneItem->setId(lane.id.c_str());
        pLaneItem->setLaneType(lane.type.c_str());
        pLaneItem->setRoadMarkColor(lane.roadMark.color.c_str());
        pLaneItem->setRoadMarkType(lane.roadMark.type.c_str());
        pLaneItem->setLaneHeight(lane.height);
    }
}

void InfoAssembling::transferLanesList(const MapInfo &mapInfo, RoadMapLane &roadMapLane)
{
    for(auto eachRoad: mapInfo.getRoad())
    {
        RoadLane roadLane;

        for(auto eachlaneSection: eachRoad.lanes.qvecLaneSection)
        {
            SectionLane sectionLane;

            for(auto eachLane: eachlaneSection.left.qvecLane)
            {
                sectionLane.append(eachLane);
            }

            for(auto eachLane: eachlaneSection.center.qvecLane)
            {
                sectionLane.append(eachLane);
            }

            for(auto eachLane: eachlaneSection.right.qvecLane)
            {
                sectionLane.append(eachLane);
            }

            roadLane.append(sectionLane);
        }

        roadMapLane.append(roadLane);
    }
}

void InfoAssembling::setRoadMapFilling(const RoadMapPaint &roadMapPaint, const RoadMapLane &roadMapLane, RoadMapItem *pRoadMapItem)
{
    for(int i = 0; i < roadMapPaint.size(); ++i)
    {
        //每个道路
        for(int j = 0; j < roadMapPaint[i].size(); ++j)
        {
            //每个车道段
            int iStartLaneIndex = stoi(roadMapLane[i][j][0].id);
            for(int k = 0; k < roadMapPaint[i][j].size(); ++k)
            {
                QPolygonF polygonF;
                Painting painting;
                if(k < iStartLaneIndex)
                {
                    //左车道
                    polygonF = __RODADATA->fillLaneData(roadMapPaint[i][j][k], roadMapPaint[i][j][k+1]);
                }
                else if(k > iStartLaneIndex)
                {
                    //右车道
                    polygonF = __RODADATA->fillLaneData(roadMapPaint[i][j][k], roadMapPaint[i][j][k-1]);
                }
                else
                {
                    //0车道
                    continue;
                }

                __RODADATA->setYOppositeNumber(polygonF);
                painting.polygonF = polygonF;
                painting.qstrColor = roadMapLane[i][j][k].type.c_str();
                pRoadMapItem->appendFilling(painting);
            }
        }
    }
}

void InfoAssembling::setRoadMapLaneLine(const RoadMapPaint &roadMapPaint, const RoadMapLane &roadMapLane, RoadMapItem *pRoadMapItem)
{
    for(int i = 0; i < roadMapPaint.size(); ++i)
    {
        //每个道路
        for(int j = 0; j < roadMapPaint[i].size(); ++j)
        {
            //每个车道段
            for(int k = 0; k < roadMapPaint[i][j].size(); ++k)
            {
                QPolygonF polygonF;
                Painting painting;
                polygonF = roadMapPaint[i][j][k];
                __RODADATA->setYOppositeNumber(polygonF);
                painting.polygonF = polygonF;
                painting.qstrColor = roadMapLane[i][j][k].roadMark.color.c_str();
                painting.qstrStyle = roadMapLane[i][j][k].roadMark.type.c_str();
                pRoadMapItem->appendLaneLine(painting);
            }
        }
    }
}

void InfoAssembling::initRoadMapPoint(const QVector<Road> &qvecAllRoad)
{
//    for (Road eachRoad: qvecAllRoad)
//    {
//        double dRoadLength = eachRoad.length;
//        QVector<QVector<QVector<QPointF> > > vecRoad;
//        for (int i = 0; i < eachRoad.vecLaneSection.size(); ++i)
//        {
////            int id = eachRoad.id;
////            if (id != 14007)
////                continue;
//            QVector<QVector<QPointF> > vecLaneSection;
//            LaneSection eachLaneSection = eachRoad.vecLaneSection[i];
//            double dLaneStart = eachLaneSection.s;
//            double dLaneEnd = 0;
//            if (i+1 == eachRoad.vecLaneSection.size())
//            {
//                dLaneEnd = dRoadLength;
//            }
//            else
//            {
//                dLaneEnd = eachRoad.vecLaneSection[i+1].s;
//            }
//            // 车道段
//            LaneOffset eachLaneOffset = eachRoad.vecLaneOffset[i];
//            //vecLaneSection = getLaneSectionPoint(eachLaneOffset, eachLaneSection, eachRoad.vecGeometry, dLaneStart, dLaneEnd);
//            vecRoad.push_back(vecLaneSection);
//        }

//        m_qvecRoadMapPoint.push_back(vecRoad);
//    }
}

LaneItem *InfoAssembling::createLaneItem(const QPolygonF &polygon, const QPolygonF &nextPolygon)
{
    LaneItem *pNaneItem = new LaneItem();
    QPolygonF laneFilling;
    laneFilling = __RODADATA->fillLaneData(polygon, nextPolygon);
    __RODADATA->setYOppositeNumber(laneFilling);
    pNaneItem->setPolygon(laneFilling);
    return pNaneItem;
}

QPolygonF InfoAssembling::getRoadShape(const RoadPoint &roadPoint)
{
    QPolygonF polygon;
    QPolygonF polygonEnd;

    for(auto laneSectionPoint: roadPoint)
    {
        for(auto geometryPoint: laneSectionPoint)
        {
            polygon.append(geometryPoint.first.at(0));
            polygonEnd.append(geometryPoint.first.at(geometryPoint.first.size() - 1));
        }
    }

    polygon = __RODADATA->fillLaneData(polygon, polygonEnd);
    __RODADATA->setYOppositeNumber(polygon);
    return polygon;
}
